//
//  CJRefreshControl.swift
//  SinaWeibo
//
//  Created by 程建 on 16/9/29.
//  Copyright © 2016年 itcast. All rights reserved.
//

import UIKit

//实时获取tableView的contentOffset(属性)变化
//刷新控件需要监听tableView的contentOffset的变化
/*
 1.添加监听者,监听属性变化
 2.实现KVO的监听方法 这个方法必须要实现,如果不程序会boom
 3.在deinit方法中移除监听者
 */

private let refreshHeight:CGFloat = 50

//枚举代表三种状态
enum RefreshStatue: Int{

    case Normal = 0 //默认状态
    
    case Pulling  //准备刷新状态
    
    case Refreshing  //正在刷新状态
}


class CJRefreshControl: UIControl {
    
    var refreshStatue: RefreshStatue = .Normal {
    
        didSet {
            switch refreshStatue {
            case .Normal:
               //跟新UI界面
                arrowIcon.isHidden = false
                tipLabel.text = "下拉起飞"
                indicator.stopAnimating()
                //刷新结束之后调整contentInset.top 判断如果上一次的刷新状态是 Refreshing状态 才减去高度
                if oldValue == RefreshStatue.Refreshing {
                    
                    UIView.animate(withDuration: 0.5, animations: {
                        
                        self.scrollView!.contentInset.top = self.scrollView!.contentInset.top - refreshHeight

                    })
                    
                }
                
                
                UIView.animate(withDuration: 0.25, animations: { 
                    self.arrowIcon.transform = CGAffineTransform.identity
                })
                
                
            case .Pulling:
                arrowIcon.isHidden = false
                tipLabel.text = "松手起飞"
                indicator.stopAnimating()
                //在动画闭包中执行箭头的转动
                UIView.animate(withDuration: 0.25, animations: { 
                    //修改箭头的transform
                    self.arrowIcon.transform = CGAffineTransform.init(rotationAngle: CGFloat(M_PI))
                })
                
                
            case .Refreshing:
                tipLabel.text = "正在起飞"
                //隐藏箭头
                arrowIcon.isHidden = true
                //开始小菊花的转动
                indicator.startAnimating()
                //刷新的时候修改scrollView的contentInset
                scrollView!.contentInset.top = scrollView!.contentInset.top + refreshHeight
                
                //能够让刷新控件能够发出 valueChanged类型的事件是不是就可以调用到loadData
                //让cjRefreshControl能够主动发出 valueChanged的事件
                self.sendActions(for: .valueChanged)
            }
        }
    }
    
    func stopAnimation() {
    
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5, execute: {
            self.refreshStatue = .Normal
        })
    }
    
    override init(frame: CGRect) {
        super.init(frame: CGRect(x: 0, y: -refreshHeight, width: ScreenWidth, height: refreshHeight))
        
        self.backgroundColor = UIColor.red
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    
    private func setupUI() {
    
        self.addSubview(arrowIcon)
        
        self.addSubview(tipLabel)
        
        self.addSubview(indicator)
        
        self.addSubview(backView)
        
        //设置约束
        tipLabel.snp.makeConstraints { (make) in
            make.centerX.equalTo(self).offset(10)
            make.centerY.equalTo(self)
        }
        
        indicator.snp.makeConstraints { (make) in
            make.right.equalTo(tipLabel.snp.left).offset(-5)
            make.centerY.equalTo(self)
        }
        
        arrowIcon.snp.makeConstraints { (make) in
            make.center.equalTo(indicator)
        }

        backView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalTo(self)
        }
    }
    //该方法是UIView
    //当改视图将要移动新的父视图的时候,系统会自动调用该方法
    //
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        
        if let fatherView = newSuperview as? UIScrollView {
            
            self.scrollView = fatherView
            //如果父视图是滚动视图,就监听contentOffset
            fatherView.addObserver(self, forKeyPath: "contentOffset", options:.new, context: nil)
        
        }
    }
    
    //监听方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        //滚动视图的contentOffset
        let offsetY = scrollView?.contentOffset.y ?? 0
        //确定临界值 -114   -(64 + 50)
        //比较两个值
        let targetY:CGFloat = -114
        
        //正在拽动
        if scrollView!.isDragging {
            
            if refreshStatue == .Normal && offsetY < targetY {
                //小于 处于准备刷新状态
                refreshStatue = .Pulling
            
            }else if refreshStatue == .Pulling && offsetY > targetY {
                //大于 默认状态
                refreshStatue = .Normal
                
            }
        }else {
            //如果是准备刷新状态,并且用户已经松手  那就应该是 正在刷新状态
            if refreshStatue == .Pulling {
                
                refreshStatue = .Refreshing
            }
            
            
        }
        
    }
    
    //移除监听者
    deinit {
        self.scrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    
    private var scrollView:UIScrollView?
    
    
    //懒加载子控制器
    //懒加载子控件
    //箭头控件
    private lazy var arrowIcon: UIImageView = UIImageView(image: #imageLiteral(resourceName: "tableview_pull_refresh"))
    //提示文字
    private lazy var tipLabel: UILabel = UILabel(title: "下拉刷新",textColor: UIColor.orange,fontSize: 14)
    //菊花按钮
    private lazy var indicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
    
    //添加下拉刷新的图片
    private lazy var backView = UIImageView(image: #imageLiteral(resourceName: "refreshbg"))

}
